<template>
	<div>
		<div class="container">
			<div class="handle-box">
				<el-select v-model="query.roomName" placeholder="教室" class="handle-select mr10">
					<el-option v-for="item in roomData" :key="item.roomId" :label="item.roomName" :value="item.roomId"></el-option>
				</el-select>
				<el-input v-model="query.deviceId" placeholder="设备ID" class="handle-input mr10"></el-input>
				<el-button type="primary" :icon="Search" @click="searchDevice">搜索</el-button>
				<el-button type="primary" :icon="Plus" @click="handleClickAddButton">新增</el-button>
        <!--新增或编辑设备信息界面-->
				<el-dialog v-model="dialogVisible" :title="titleName" @close="resetForm(deviceFormRef)">
					<el-form
							ref="deviceFormRef"
							:model="deviceForm"
							:rules="devicerules"
							label-width="120px"
							class="demo-ruleForm"
							:size="formSize"
							status-icon
					>
						<el-form-item label="设备ID" prop="ID">
							<el-input v-model="deviceForm.ID" :disabled="inputDisabled"/>
						</el-form-item>
						<el-form-item label="名称" prop="name">
							<el-input v-model="deviceForm.name" />
						</el-form-item>
						<el-form-item label="设备类型" prop="type">
							<el-select v-model="deviceForm.type" placeholder="请选择设备类型">
								<el-option v-for="item in deviceTypeData" :key="item.typeId" :label="item.typeName" :value="item.typeName" />
							</el-select>
						</el-form-item>
						<el-form-item label="设备MAC" prop="mac">
							<el-input v-model="deviceForm.mac" :disabled="inputDisabled" />
						</el-form-item>
						<el-form-item label="教室" prop="address">
							<el-select v-model="deviceForm.address" placeholder="请选择设备的所在地址">
								<el-option v-for="item in roomData" :label="item.roomName" :value="item.roomId" />
							</el-select>
						</el-form-item>
						<el-form-item label="状态" prop="state">
							<el-radio-group v-model="deviceForm.state">
								<el-radio label="1">启用</el-radio>
								<el-radio label="0">禁用</el-radio>
							</el-radio-group>
						</el-form-item>
						<el-form-item label="备注" prop="note">
							<el-input v-model="deviceForm.note" type="textarea" />
						</el-form-item>
						<el-form-item label="经度">
							<el-input v-model="deviceForm.longitude"/>
						</el-form-item>
						<el-form-item label="维度">
							<el-input v-model="deviceForm.latitude"/>
						</el-form-item>
						<el-form-item>
							<div ref="mapChart" class="map" style="width: 800px; height: 400px"></div>
						</el-form-item>
						<el-form-item>
							<el-button type="primary" @click="handleSubmit">{{submitButton}}</el-button>
							<el-button @click="dialogVisible = false">取消</el-button>
						</el-form-item>
					</el-form>
				</el-dialog>
			</div>
			<el-table :data="deviceData" style="width: 100%">
				<el-table-column label="设备ID" prop="ID" />
				<el-table-column label="设备mac" prop="mac" />
				<el-table-column label="设备名称" prop="name" />
				<el-table-column label="设备类型" prop="type" />
				<el-table-column label="教室" prop="address" />
				<el-table-column label="设备状态" prop="deviceStatus" />
				<el-table-column label="备注" prop="note" />
				<el-table-column label="最近上线时间" prop="onlineTime" />
				<el-table-column label="操作" prop="$1">
					<template #default="scope">
						<el-button size="small" @click="handleEditButton(scope)"
						>编辑</el-button
						>
						<el-button
								size="small"
								type="danger"
								@click="handleDelete(scope.$index, scope.row)"
						>删除</el-button
						>
					</template>
				</el-table-column>
			</el-table>
		</div>
	</div>
</template>

<script setup lang="ts" name="editdevice">
import {ref, reactive, computed, nextTick, onMounted} from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus'
import { Delete, Edit, Search, Plus } from '@element-plus/icons-vue';
import API from "../utils/axios";
import * as echarts from 'echarts';
import DemoRoom from "../MapJson/map.json"

const mapChart = ref();
let myMapChart : echarts.EChartOption;
// 坐标数据
const coordinate = ref([]);
// 新增坐标数据
const addCoordinate = ref([]);

// 点击新增按钮事件
const handleClickAddButton = () => {
	controls('add')
	// 在调用loadMap函数之前，检查是否已经存在地图实例
	if (!myMapChart || !echarts.getInstanceByDom(mapChart.value)) {
		setTimeout(() => {
			loadMap();
		},100)
	} else {
		// 如果地图实例已经存在，可以选择更新地图数据而不是重新加载地图
		updateSeriesData();
		// 可以在这里调用更新数据的逻辑
	}
}

// 点击编辑按钮事件
let selectDeviceId = ref()
const handleEditButton = (scope : any) => {
	controls('edit');
	handleEdit(scope.$index, scope.row)
	selectDeviceId.value = scope.row.ID;
	// 在调用loadMap函数之前，检查是否已经存在地图实例
	if (!myMapChart || !echarts.getInstanceByDom(mapChart.value)) {
		setTimeout(() => {
			loadMap();
		},100)
	} else {
		// 如果地图实例已经存在，可以选择更新地图数据而不是重新加载地图
		updateSeriesData();
		// 可以在这里调用更新数据的逻辑
	}
}

// 点击删除按钮事件
const handleDelete = (index: number, row: any) => {
	deviceData.value.splice(index,1)
	const formData = new FormData();
	formData.append("deviceNumber", row.ID)
	API.post("/DeviceController/deleteDevice", formData)
			.then((res) => {
				ElMessage(res.data.data);
			})
}

// 点击提交按钮事件
const handleSubmit = async () => {
  if (submitButton.value == "添加"){
		await addDevice();
	}else if (submitButton.value == "保存"){
		await editDevice();
	}
	await getLightDevice();
	dialogVisible.value = false;
}

// 加载地图
const loadMap = () => {
	// 实例化Echarts
	myMapChart = echarts.init(mapChart.value, "dark");
	echarts.registerMap("Room", DemoRoom);
	const map_option = {
		title: {
			text: '设备分布图',
			left: 'center',
			bottom: 10
		},
		tooltip: {
			formatter: function (params) {
				// 获取设备编号和设备名称
				let deviceName = params.data.deviceName;
				let deviceId = params.data.deviceId;
				// 自定义展示的内容
				return `设备编号: ${deviceId}<br>设备名称: ${deviceName}`;
			},
		},
		geo: {
			tooltip: {
				show: true
			},
			map: 'Room',
			roam: true,
			itemStyle: {
				// 定义地图初始样式
				normal: {
					areaColor: '#e8e8e8', // 地图区域的颜色
					borderColor: '#000000'
				},
				// 定义鼠标悬浮时的样式
				emphasis: {
					areaColor: '#376fe7' // 鼠标悬浮时地图区域的颜色，根据需求调整
				},
			},
			label: {
				normal: {
					show: true, // 设置为true，使得地图上的区域名称始终显示
					textStyle: {
						color: '#000', // 文本颜色
						fontSize: 20 // 文本字体大小
					}
				},
				emphasis: {
					show: true,
					textStyle: {
						color: '#fff' // 鼠标悬浮时文本颜色
					}
				}
			}
		},
		series: {
			type: 'effectScatter',
			coordinateSystem: 'geo',
			geoIndex: 0,
			symbolSize: function (params: any) {
				return (params[2] / 100) * 15 + 5;
			},
			itemStyle: {
				color: function (params){
					return editColor(params.data.deviceId);
				}
			},
			encode: {
				tooltip: 2
			},
			data: coordinate.value
		}
	};
// 渲染数据
	myMapChart.setOption(map_option);
	// 添加点击事件监听器
	myMapChart.on('click', (params) => {
		// 获取经纬度坐标
		let [pointInPixel,pointInGeo] = myMapChart.convertFromPixel('geo', [params.event.offsetX, params.event.offsetY]);
		// 判断新增坐标数组中是否已经存在散点坐标
		// 如果存在，则移除旧散点坐标，并新增
		// 如果不存在，则直接新增
		if (addCoordinate.value.length === 1){
			addCoordinate.value.shift();
			coordinate.value.pop();
		}
		addCoordinate.value.push([pointInPixel,pointInGeo,100]);
		deviceForm.longitude = pointInPixel;
		deviceForm.latitude = pointInGeo;
		coordinate.value.push(addCoordinate.value[0]);
		updateSeriesData();
	});
}

// 编辑设备变色，显示当前操作设备
const editColor = ((deviceId : any) => {
	if (deviceForm.ID == deviceId){
		return '#ae2e2e';
	}else {
		return '#5db556';
	}
});


// 更新地图视图
const updateSeriesData = () => {
	const map_option = {
		series: {
			itemStyle: {
				color: function (params){
					return editColor(params.data.deviceId);
				}
			},
			data : coordinate.value
		}
	}
	myMapChart.setOption(map_option);
};

// 编辑数据
const editDeviceData = {
	deviceNumber: '',
	deviceName: '',
	deviceType: '',
	deviceMac: '',
	deviceStatus: '',
	roomNumber: '',
	deviceNote: '',
	deviceLongitude: 0,
	deviceLatitude: 0,
}
// 编辑设备数据
const editDevice = () => {
	editDeviceData.deviceNumber = deviceForm.ID;
	editDeviceData.deviceName = deviceForm.name;
	editDeviceData.deviceType = deviceForm.type;
	editDeviceData.deviceMac = deviceForm.mac;
	editDeviceData.roomNumber = deviceForm.address;
	editDeviceData.deviceStatus = deviceForm.state;
	editDeviceData.deviceNote = deviceForm.note;
	editDeviceData.deviceLongitude = deviceForm.longitude;
	editDeviceData.deviceLatitude = deviceForm.latitude;
	API.post("/DeviceController/editDevice", editDeviceData)
			.then((res) => {
				ElMessage(res.data.data);
			})
			.catch((err) => {return err})
}

// 提交按钮属性
let submitButton = ref('添加');
// 新增设备数据
const addDeviceData = {
	deviceNumber: '',
	deviceName: '',
	deviceType: '',
	deviceMac: '',
	deviceStatus: '',
	roomNumber: '',
	deviceNote: '',
	deviceLongitude: 0,
	deviceLatitude: 0,
}
// 新增设备
const addDevice = () => {
	addDeviceData.deviceNumber = deviceForm.ID;
	addDeviceData.deviceName = deviceForm.name;
	addDeviceData.deviceType = deviceForm.type;
	addDeviceData.deviceMac = deviceForm.mac;
	addDeviceData.roomNumber = deviceForm.address;
	addDeviceData.deviceStatus = deviceForm.state;
	addDeviceData.deviceNote = deviceForm.note;
	addDeviceData.deviceLongitude = deviceForm.longitude;
	addDeviceData.deviceLatitude = deviceForm.latitude;
	API.post("/DeviceController/addDevice", addDeviceData)
			.then((res) => {
				if (res.data.data == "编号重复"){
					ElMessage("编号已存在！")
				}else if (res.data.data == "添加成功"){
					ElMessage("添加成功！")
				}else if (res.data.data == "添加失败"){
					ElMessage("添加失败!")
				}
			})
			.catch((err) => {return err})
}

// 查询数据（输入框）
const query = ref({
	roomName: '',
	deviceId: '',
});
// 查询设备数据
const searchDeviceData = {
	roomName: '',
	deviceName: '',
}
// 查询设备信息
const searchDevice = () => {
	searchDeviceData.roomName = query.value.roomName;
	searchDeviceData.deviceName = query.value.deviceId;
	if (searchDeviceData.roomName.length == 0 && searchDeviceData.deviceName.length == 0){
		getLightDevice();
	}else {
		API.post("/DeviceController/searchDevice", searchDeviceData)
				.then((res) => {
					deviceData.value  = res.data.data.map((item : any) => {
						let Status  = '';
						if (item.deviceStatus == 0){
							Status = '离线';
						}else{
							Status = '在线';
						}
						return { ID : item.deviceNumber, name: item.deviceName, type : item.deviceType, mac : item.deviceMac, address : item.roomName,
							workStatus : item.deviceWorkStatus, note : item.deviceNote, onlineTime : item.deviceOnlineTime, deviceStatus : Status}
					})
				})
				.catch((err) => {return err})
	}
}

// 设备类型数据
const deviceTypeData = ref([]);
// 获取设备类型数据
const getDeviceType = () => {
	API.post("/DeviceController/getDeviceType")
			.then((res) => {
				deviceTypeData.value = res.data.data.map((item : any) => {
					return {typeId : item.typeId, typeName : item.deviceType}
				})
			})
			.catch((err) => {return err})
};


// 教室数据
const roomData = ref([]);
// 获取教室数据
const getClassRoom = () => {
	API.post("/DeviceController/getAllRoom")
			.then((res) => {
				roomData.value = res.data.data.map((item : any) => {
					return {roomName : item.roomName, roomId : item.roomNumber}
				})
			})
			.catch((err) => {return err})
};

// 灯光设备数据
const deviceData = ref([]);
// 获取灯光设备数据
const getLightDevice = () => {
	API.post('/DeviceController/getAllDevice')
			.then((res) => {
				const newData  = res.data.data.map((item : any) => {
					let Status  = '';
					if (item.deviceStatus == 0){
						Status = '离线';
					}else{
						Status = '在线';
					}
					return {
						ID : item.deviceNumber,
						name: item.deviceName,
						type : item.deviceType,
						mac : item.deviceMac,
						address : item.roomName,
						workStatus : item.deviceWorkStatus,
						note : item.deviceNote,
						onlineTime : item.deviceOnlineTime,
						deviceStatus : Status,
						longitude : item.deviceLongitude,
						latitude : item.deviceLatitude,
					}
				})
				deviceData.value = newData;
			})
			.catch((err) => {
				return err
			})
};

// 异步加载设备和灯光设备数据并完成渲染
onMounted(() => {
	// 异步获取
	(async () => {
		await getDeviceType();
		await getClassRoom();
		await getLightDevice();
	})()
})

// 设置表单内容不可更改变量（默认为可见）
let inputDisabled = ref(false);
// 设置表单title变量
let titleName = ref('表单')
// 设置新增或编辑逻辑行为判断
const controls = (control : string) => {
	if (control === 'edit'){
		dialogVisible.value = true;
		inputDisabled.value = true;
		titleName.value = '编辑设备';
		submitButton.value = '保存';
		// 弹出编辑框时加载散点数据
		deviceData.value.map((item : any) => {
			if (item.longitude != null && item.latitude){
				coordinate.value.push({value : [item.longitude,item.latitude,50], deviceName : item.name, deviceId : item.ID})
			}
		});
	}else if(control === 'add') {
		dialogVisible.value = true;
		inputDisabled.value = false;
		titleName.value = '新增设备';
		submitButton.value = '添加';
		deviceForm.latitude = 0;
		deviceForm.longitude = 0;
		// 弹出编辑框时加载散点数据
		deviceData.value.map((item : any) => {
			if (item.longitude != null && item.latitude){
				coordinate.value.push({value : [item.longitude,item.latitude,50], deviceName : item.name, deviceId : item.ID})
			}
		});
	}
}

// 将内容填充到编辑框中
const handleEdit = (index: number, row: any) => {
	deviceForm.ID = row.ID
	deviceForm.name = row.name
	deviceForm.type = row.type
	deviceForm.mac = row.mac
	deviceForm.address = ''
	deviceForm.longitude = row.longitude
	deviceForm.latitude = row.latitude
	if (row.deviceStatus == 0){
		deviceForm.state = "0"
	}else if (row.deviceStatus == 1){
		deviceForm.state = "1"
	}
	}

//隐藏提示框
const dialogVisible = ref(false)

interface DeviceForm {
	ID: string
	name: string
	type: string
	mac: string
	state: string;
	address: string
	note: string
	longitude: number,
	latitude: number
}

const formSize = ref('default')
const deviceFormRef = ref<FormInstance>()
const deviceForm = reactive<DeviceForm>({
	ID: '',
	name: '',
	type: '',
	mac: '',
	state: '',
	address: '',
	note: '',
	longitude : 0,
	latitude: 0
})
const devicerules = reactive<FormRules<DeviceForm>>({
	ID: [
		{ required: true, message: '设备ID不能为空', trigger: 'blur' },
		{ min: 1, max: 5, message: '设备ID长度为1-5位', trigger: 'blur' },
	],
	name: [
		{ required: true, message: '设备名称不能为空', trigger: 'blur' },
		{ min: 1, max: 20, message: '设备名称长度为1-20位', trigger: 'blur' },
	],
	mac: [
		{ required: true, message: '设备mac不能为空', trigger: 'blur' },
		{ min: 1, max: 20, message: '设备名称长度为1-20位', trigger: 'blur' },
	],
	type: [
		{
			required: true,
			message: '设备类型不能为空',
			trigger: 'change',
		},
	],
	address: [
		{
			required: true,
			message: '设备所在位置不能为空',
			trigger: 'change',
		},
	],
	state: [
		{ required: true, message: '账号状态不能为空', trigger: 'change' },
	],
	longitude: [
		{ required: true, message: '设备名称不能为空', trigger: 'blur' },
	],
	latitude: [
		{ required: true, message: '设备名称不能为空', trigger: 'blur' },
	]
})

//重置表单
const resetForm = (deviceFormRef: FormInstance | undefined) => {
	if (!deviceFormRef) return
	deviceFormRef.resetFields()
}
</script>

<style scoped>
.dialog-footer button:first-child {
	margin-right: 10px;
}

.handle-box {
	margin-bottom: 20px;
}

.handle-select {
	width: 160px;
}

.handle-input {
	width: 300px;
}
</style>
